#include "Injector.h"

#define PROC_ID "Gw2.exe"

int findProcess();

namespace Injection{

	Injector::Injector(void)
	{
	}


	Injector::~Injector(void)
	{
	}


	bool Injector::inject(){
		int procId, check;
		HANDLE hProcess, hThread;
		LPVOID addr, arg;
		char *dll = "Overlay.dll";
		auto cleanup = [&](bool ret)->bool{CloseHandle(hProcess); return ret;};

		while((procId = findProcess()) == 0) Sleep(1000);
		hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
		if(hProcess == 0)
			return false;
		addr = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
		if(addr == 0)
			return cleanup(false);
		arg = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(dll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if(arg == 0)
			return cleanup(false);
		check = WriteProcessMemory(hProcess, arg, dll, strlen(dll), NULL);
		if(check == 0)
			return cleanup(false);
		hThread = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
		if(hThread == 0)
			return cleanup(false);
		else
			return cleanup(true);
	}

};


int findProcess(){
	DWORD processes[1024], cbNeeded, cProcesses, cbNeed;
	HANDLE hProcess;
	HMODULE hMod;
	unsigned int i;
	TCHAR procName[MAX_PATH] = TEXT("unknown");

	if(!EnumProcesses(processes, sizeof(processes), &cbNeeded))
		return -1;
	cProcesses = cbNeeded/sizeof(DWORD);
	for(i = 0; i < cProcesses; i++){
		if(processes[i] != 0){
			hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processes[i]);
			if(hProcess != 0 && EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeed)){
				GetModuleBaseName(hProcess, hMod, procName, sizeof(procName)/sizeof(TCHAR));
				if(wcscmp(TEXT(PROC_ID), procName) == 0){
					CloseHandle(hProcess);
					return processes[i];
				}
			}
			if(hProcess != 0)
				CloseHandle(hProcess);
		}
	}
	return 0;
}